package net.xisberto.phonetodesktop;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.DropboxAPI.DropboxFileInfo;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.exception.DropboxUnlinkedException;
import com.dropbox.client2.session.AccessTokenPair;
import com.dropbox.client2.session.AppKeyPair;
import com.dropbox.client2.session.Session.AccessType;

public class DropboxSynced {
	final static protected String
		APP_KEY = "5ukwzkijk54y0op",
		APP_SECRET = "owm39jfssipjm16";
	final static protected AccessType ACCESS_TYPE = AccessType.APP_FOLDER;
	
	final static public String
			PREFERENCES_NAME = "PhoneToDesktop",
			PREFERENCES_KEY_KEY = "key",
			PREFERENCES_KEY_SECRET = "secret";
	
	final static protected String FILENAME = "entries.json";

	public DropboxAPI<AndroidAuthSession> mDBApi;
	protected DropboxFileInfo file;
	private Context context;
	
	public DropboxSynced(Context context) {
		this.context = context;
		
		AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
		AndroidAuthSession session = new AndroidAuthSession(appKeys, ACCESS_TYPE);
		mDBApi = new DropboxAPI<AndroidAuthSession>(session);

        authorize();
	}

	/**
	 * Checks if the authorization keys are saved in this phone.
	 * @return false if the keys are a empty String, true otherwise.
	 */
	protected boolean isAuthorizationStored() {
		AccessTokenPair access = getStoredKeys();
		if (access.key.equals("")) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * Tries to authorize the application (login).
	 * @return true if the login was successful, false otherwise.
	 */
	public boolean authorize() {
		if (isAuthorizationStored()) {
			AccessTokenPair access = getStoredKeys();
			mDBApi.getSession().setAccessTokenPair(access);
			return mDBApi.getSession().isLinked();
		} else {
			return false;
		}
	}
	
	/**
	 * Checks if this application is authorized in the Dropbox account of the
	 * user. Updates local keys according to the status of the Dropbox account.
	 * @return true if authorized, false if not.
	 */
	protected boolean isAuthorized() {
		if (isAuthorizationStored()) {
			return mDBApi.getSession().isLinked();
		} else {
			return false;
		}
	}

    protected void storeKeys(String key, String secret) {
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
		SharedPreferences.Editor editor = prefs.edit();
		editor.putString(PREFERENCES_KEY_KEY, key);
		editor.putString(PREFERENCES_KEY_SECRET, secret);
		editor.commit();
	}
	
	protected AccessTokenPair getStoredKeys() {
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
		return new AccessTokenPair(prefs.getString(PREFERENCES_KEY_KEY, ""), prefs.getString(PREFERENCES_KEY_SECRET, ""));
	}
	
    protected void removeKeys() {
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
		SharedPreferences.Editor editor = prefs.edit();
		editor.clear();
		editor.commit();
	}
    
	protected ByteArrayOutputStream download(String filename) throws DropboxUnlinkedException, DropboxException {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		file = mDBApi.getFile(filename, null, outputStream, null);
		return outputStream;
	}
	
	protected void upload(ByteArrayOutputStream outputStream, String filename) throws DropboxUnlinkedException, DropboxException {
		ByteArrayInputStream content = new ByteArrayInputStream(outputStream.toByteArray());
		if (file == null) {
			//If the file doesn't exists in cloud, the file attribute is null
			mDBApi.putFile(filename, content, outputStream.toByteArray().length, null, null);
		} else {
			mDBApi.putFile(filename, content, outputStream.toByteArray().length, file.getMetadata().rev, null);
		}
	}
	
}
